music = {
    'A': {'s1': 2., 's2': 3., 's3': 2., 's4': 0., 's5': -1., 's6': 1.},
    'B': {'s1': 1., 's2': 0., 's3': 1., 's4': 3., 's5': 2., 's6': 1.},
    'C': {'s1': 2., 's2': 1., 's4': 0., 's6': 1.},
    'D': {'s2': 0., 's3': 1., 's4': 1., 's6': 2.},
    'E': {'s1': 1., 's2': 1., 's3': 3., 's4': 3., 's5': 0., 's6': 1.},
    'F': {'s1': 0., 's2': -1., 's4': 2., 's5': 2., 's6': 0.},
    'G': {'s2': 2., 's4': -1., 's5': 2.}}

from math import sqrt

def sim_l2(u1, u2):
    sl = {}
    for s in u1:
        if s in u2:
            sl[s] = 1
    if len(sl) == 0:
        return 0
    l2 = sqrt(sum([(u1[s] - u2[s]) ** 2 for s in sl]))
    sim = 1 / (1 + l2)
    return sim


def sim_pearson(u1, u2):
    sl = {}
    for s in u1:
        if s in u2:
            sl[s] = 1
    if len(sl) == 0:
        return 0
    n = len(sl)
    sum_x = sum([u1[s] for s in sl])
    sum_y = sum([u2[s] for s in sl])
    sum_x2 = sum([u1[s] ** 2 for s in sl])
    sum_y2 = sum([u2[s] ** 2 for s in sl])
    sum_xy = sum([u1[s] * u2[s] for s in sl])
    num1 = sum_xy - (sum_x * sum_y / n)
    num2 = sqrt((sum_x2 - sum_x ** 2 / n) * (sum_y2 - sum_y ** 2 / n))
    if num2 == 0:
        return 0
    sim = num1 / num2
    return sim

user_list= ['A','B','C','D','E','F','G']
for u1 in user_list:
    for u2 in user_list:
        if u1 < u2:
            print("{:s}-{:s}: {:f}".format(u1, u2, sim_l2(music[u1], music[u2])))
    print("---------------------")


def transformPrefs(prefs):
    result = {}
    for user in prefs:
        for song in prefs[user]:
            result.setdefault(song, {})
            # Flip song and user
            result[song][user] = prefs[user][song]
    return result


music2 = transformPrefs(music)

song_list = ['s1','s2','s3','s4','s5','s6']
for s1 in song_list:
    for s2 in song_list:
        if s1 < s2:
            print("{:s}-{:s}: {:f}".format(s1, s2, sim_l2(music2[s1], music2[s2])))
    print("---------------------")
